package com.xxx.topapplication;

import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

public class FloatWindowView extends LinearLayout implements View.OnTouchListener, View.OnClickListener, View.OnLongClickListener {


    public static int viewWidth;
    public static int viewHeight;
    private Rect mViewRect;

    private ImageView mImgAppLogo;
    private TextView mTvAppName;
    private TextView mTvAppPkg;
    private TextView mTvAppVer;
    private String mApkPath;
    private WeakReference<Context> mWeakContext;

    /**
     * 用于更新悬浮窗的位置
     */
    private WindowManager windowManager;

    /**
     * 记录系统状态栏的高度
     */
    private static int statusBarHeight;

    /**
     * 记录当前手指位置在屏幕上的横坐标值
     */
    private float xInScreen;

    /**
     * 记录当前手指位置在屏幕上的纵坐标值
     */
    private float yInScreen;

    /**
     * 记录手指按下时在屏幕上的横坐标的值
     */
    private float xDownInScreen;

    /**
     * 记录手指按下时在屏幕上的纵坐标的值
     */
    private float yDownInScreen;

    /**
     * 记录手指按下时在小悬浮窗的View上的横坐标的值
     */
    private float xInView;

    /**
     * 记录手指按下时在小悬浮窗的View上的纵坐标的值
     */
    private float yInView;

    private WindowManager.LayoutParams mParams;

    public FloatWindowView(Context context) {
        super(context);
        windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        mWeakContext = new WeakReference<>(context);
        LayoutInflater.from(context).inflate(R.layout.float_window, this);
        View view = findViewById(R.id.float_window_layout);
        viewWidth = view.getLayoutParams().width;
        viewHeight = view.getLayoutParams().height;

        mImgAppLogo = (ImageView) findViewById(R.id.imgAppLogo);
        mImgAppLogo.setOnClickListener(this);
        mImgAppLogo.setOnLongClickListener(this);
        mTvAppName = (TextView) findViewById(R.id.tvAppName);
        mTvAppPkg = (TextView) findViewById(R.id.tvAppPkg);
        mTvAppVer = (TextView) findViewById(R.id.tvAppVer);

        setOnTouchListener(this);

        mViewRect = new Rect();
        this.getGlobalVisibleRect(mViewRect);
    }

    public FloatWindowView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FloatWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public FloatWindowView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }


    public void setParams(WindowManager.LayoutParams params) {
        mParams = params;
    }
    public void setAppLogo(Drawable logo) {
        mImgAppLogo.setImageDrawable(logo);
    }
    public void setAppName(String name) {
        mTvAppName.setText(name);
    }
    public void setAppPkg(String pkg) {
        mTvAppPkg.setText(pkg);
    }
    public void setApkPath(String apkPath) {
        mApkPath = apkPath;
    }
    public void setAppVer(String appVersion) {
        mTvAppVer.setText(appVersion);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 手指按下时记录必要数据,纵坐标的值都需要减去状态栏高度
                xInView = event.getX();
                yInView = event.getY();
                xDownInScreen = event.getRawX();
                yDownInScreen = event.getRawY() - getStatusBarHeight();
                xInScreen = event.getRawX();
                yInScreen = event.getRawY() - getStatusBarHeight();
                break;
            case MotionEvent.ACTION_MOVE:
                xInScreen = event.getRawX();
                yInScreen = event.getRawY() - getStatusBarHeight();
                // 手指移动的时候更新小悬浮窗的位置
                updateViewPosition();
                break;
            case MotionEvent.ACTION_UP:
                // 如果手指离开屏幕时，xDownInScreen和xInScreen相等，且yDownInScreen和yInScreen相等，则视为触发了单击事件。
                if (xDownInScreen == xInScreen && yDownInScreen == yInScreen) {
                    //MyWindowManager.getInstance().showBigWindow(getContext());
                }
                break;
            default:
                break;
        }
        return true;
    }

    /**
     * 更新小悬浮窗在屏幕中的位置。
     */
    private void updateViewPosition() {
        mParams.x = (int) (xInScreen - xInView);
        mParams.y = (int) (yInScreen - yInView);
        windowManager.updateViewLayout(this, mParams);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v.getId()==R.id.imgAppLogo) {
            return onImageViewTouch(v, event);
        }
        return false;
    }


    private boolean onImageViewTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            v.setAlpha(0.5f);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            v.setAlpha(1);
        }
        return false;
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.imgAppLogo) {
            String path = "/sdcard/"+mTvAppPkg.getText().toString()+".apk";
            if (copyFile(mApkPath, path)) {
                Toast.makeText(mWeakContext.get(), "文件路径: "+path, Toast.LENGTH_LONG).show();
            }
        }
    }


    @Override
    public boolean onLongClick(View v) {
        if (v.getId() == R.id.imgAppLogo) {
            // 长按转到应用设置
            String pkg = mTvAppPkg.getText().toString();
            if (!TextUtils.isEmpty(pkg)) {
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.setData(Uri.fromParts("package", pkg, null));
                mWeakContext.get().startActivity(intent);
            }
            return true;
        }
        return false;
    }


    public boolean copyFile(String oldPathName, String newPathName) {
        try {
            File oldFile = new File(oldPathName);
            if (!oldFile.exists()) {
                Log.e("--Method--", "copyFile:  oldFile not exist.");
                return false;
            } else if (!oldFile.isFile()) {
                Log.e("--Method--", "copyFile:  oldFile not file.");
                return false;
            } else if (!oldFile.canRead()) {
                Log.e("--Method--", "copyFile:  oldFile cannot read.");
                return false;
            }

            /* 如果不需要打log，可以使用下面的语句
            if (!oldFile.exists() || !oldFile.isFile() || !oldFile.canRead()) {
                return false;
            }
            */

            FileInputStream fileInputStream = new FileInputStream(oldPathName);
            FileOutputStream fileOutputStream = new FileOutputStream(newPathName);
            byte[] buffer = new byte[1024];
            int byteRead;
            while (-1 != (byteRead = fileInputStream.read(buffer))) {
                fileOutputStream.write(buffer, 0, byteRead);
            }
            fileInputStream.close();
            fileOutputStream.flush();
            fileOutputStream.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 用于获取状态栏的高度。
     *
     * @return 返回状态栏高度的像素值。
     */
    private int getStatusBarHeight() {
        if (statusBarHeight == 0) {
            try {
                Class<?> c = Class.forName("com.android.internal.R$dimen");
                Object o = c.newInstance();
                Field field = c.getField("status_bar_height");
                int x = (Integer) field.get(o);
                statusBarHeight = getResources().getDimensionPixelSize(x);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return statusBarHeight;
    }
}
